home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 August: Tool Chest / Dev.CD Aug 95 TC / Dev.CD Aug 95 TC.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / interp / brkpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  5.8 KB  |  247 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: brkpt.c,v 1.6 94/10/05 21:01:11 nkramer Exp $
  27. *
  28. * This file implements breakpoints.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33.  
  34. #include "mindy.h"
  35. #include "weak.h"
  36. #include "thread.h"
  37. #include "driver.h"
  38. #include "gc.h"
  39. #include "interp.h"
  40. #include "bool.h"
  41. #include "print.h"
  42. #include "../comp/byteops.h"
  43. #include "brkpt.h"
  44.  
  45. static int NextBreakpoint = 1;
  46.  
  47.  
  48. /* Byte breakpoints. */
  49.  
  50. struct byte_brkpt_info {
  51.     int id;
  52.     obj_t component;
  53.     int pc;
  54.     int orig_byte;
  55.     struct byte_brkpt_info *next;
  56. };
  57.  
  58. static struct byte_brkpt_info *ByteBreakpoints = NULL;
  59.  
  60. static struct byte_brkpt_info *find_byte_breakpoint(obj_t component, int pc)
  61. {
  62.     struct byte_brkpt_info **prev, *info;
  63.  
  64.     prev = &ByteBreakpoints;
  65.  
  66.     while ((info = *prev) != NULL) {
  67.     if (WEAK(info->component)->broken) {
  68.         printf("breakpoint %d garbage collected\n", info->id);
  69.         *prev = info->next;
  70.         free(info);
  71.     }
  72.     else if (WEAK(info->component)->object == component && info->pc == pc)
  73.         return info;
  74.     else
  75.         prev = &info->next;
  76.     }
  77.     return NULL;
  78. }
  79.  
  80. int install_byte_breakpoint(obj_t component, int pc)
  81. {
  82.     struct byte_brkpt_info *info = find_byte_breakpoint(component, pc);
  83.     int nconst;
  84.     unsigned char *ptr;
  85.  
  86.     if (info)
  87.     return info->id;
  88.  
  89.     ptr = (unsigned char *)component + pc;
  90.  
  91.     nconst = COMPONENT(component)->n_constants;
  92.     if (ptr < (unsigned char *)(&COMPONENT(component)->constant[nconst]))
  93.     return -1;
  94.     if (ptr > obj_ptr(unsigned char *, component)+COMPONENT(component)->length)
  95.     return -1;
  96.  
  97.     info = malloc(sizeof(*info));
  98.     info->id = NextBreakpoint++;
  99.     info->component = make_weak_pointer(component);
  100.     info->pc = pc;
  101.     info->orig_byte = *ptr;
  102.     *ptr = op_BREAKPOINT;
  103.     info->next = ByteBreakpoints;
  104.     ByteBreakpoints = info;
  105.  
  106.     return info->id;
  107. }
  108.  
  109. int original_byte(obj_t component, int pc)
  110. {
  111.     struct byte_brkpt_info *info = find_byte_breakpoint(component, pc);
  112.  
  113.     if (info)
  114.     return info->orig_byte;
  115.     else
  116.     return op_TRAP;
  117. }
  118.  
  119. static void skip_byte_breakpoint(struct thread *thread)
  120. {
  121.     struct byte_brkpt_info *info
  122.     = find_byte_breakpoint(thread->component, thread->pc);
  123.  
  124. #if SLOW_FUNCTION_POINTERS
  125.     thread->advance = NULL;
  126. #else
  127.     thread->advance = interpret_next_byte;
  128. #endif
  129.  
  130.     if (info) {
  131.     thread->pc++;
  132.     interpret_byte(info->orig_byte, thread);
  133.     }
  134.     else
  135.     interpret_next_byte(thread);
  136. }
  137.  
  138. void handle_byte_breakpoint(struct thread *thread)
  139. {
  140.     struct byte_brkpt_info *info
  141.     = find_byte_breakpoint(thread->component, --thread->pc);
  142.  
  143.     if (info)
  144.     thread->advance = skip_byte_breakpoint;
  145.  
  146.     pause(pause_HitBreakpoint);
  147. }
  148.  
  149.  
  150.  
  151. /* Breakpoint removal. */
  152.  
  153. void remove_breakpoint(int id)
  154. {
  155.     struct byte_brkpt_info **byte_prev, *byte_info;
  156.     boolean removed = FALSE;
  157.  
  158.     byte_prev = &ByteBreakpoints;
  159.     while ((byte_info = *byte_prev) != NULL) {
  160.     if (WEAK(byte_info->component)->broken) {
  161.         if (byte_info->id == id)
  162.         removed = TRUE;
  163.         else
  164.         printf("breakpoint %d garbage collected\n", byte_info->id);
  165.         *byte_prev = byte_info->next;
  166.         free(byte_info);
  167.     }
  168.     else if (byte_info->id == id) {
  169.         unsigned char *ptr
  170.         = (unsigned char *)(WEAK(byte_info->component)->object)
  171.             + byte_info->pc;
  172.         *ptr = byte_info->orig_byte;
  173.         *byte_prev = byte_info->next;
  174.         free(byte_info);
  175.         removed = TRUE;
  176.     }
  177.     else
  178.         byte_prev = &byte_info->next;
  179.     }
  180.  
  181.     if (!removed)
  182.     printf("No breakpoint %d\n", id);
  183. }
  184.  
  185.     
  186.  
  187. /* Breakpoint listing. */
  188.  
  189. static void list_breakpoints_aux(struct byte_brkpt_info **byte_prev)
  190. {
  191.     struct byte_brkpt_info *byte_info = *byte_prev;
  192.  
  193.     if (byte_info == NULL) {
  194.     }
  195.     else if (WEAK(byte_info->component)->broken) {
  196.     printf("breakpoint %d garbage collected\n", byte_info->id);
  197.     *byte_prev = byte_info->next;
  198.     free(byte_info);
  199.     list_breakpoints_aux(byte_prev);
  200.     }
  201.     else {
  202.     obj_t component, debug_name;
  203.  
  204.     list_breakpoints_aux(&byte_info->next);
  205.  
  206.     printf("%2d  pc %d in ", byte_info->id, byte_info->pc);
  207.     component = WEAK(byte_info->component)->object;
  208.     debug_name = COMPONENT(component)->debug_name;
  209.     if (debug_name != obj_False)
  210.         print(debug_name);
  211.     else
  212.         print(component);
  213.     }
  214. }
  215.  
  216. void list_breakpoints(void)
  217. {
  218.     if (ByteBreakpoints != NULL) {
  219.     printf("id  where\n");
  220.     list_breakpoints_aux(&ByteBreakpoints);
  221.     }
  222.     else
  223.     printf("no breakpoints\n");
  224. }
  225.  
  226.  
  227.  
  228. /* GC routines. */
  229.  
  230. void scavenge_brkpt_roots(void)
  231. {
  232.     struct byte_brkpt_info **byte_prev, *byte_info;
  233.  
  234.     byte_prev = &ByteBreakpoints;
  235.     while ((byte_info = *byte_prev) != NULL) {
  236.     if (WEAK(byte_info->component)->broken) {
  237.         printf("breakpoint %d garbage collected\n", byte_info->id);
  238.         *byte_prev = byte_info->next;
  239.         free(byte_info);
  240.     }
  241.     else {
  242.         scavenge(&byte_info->component);
  243.         byte_prev = &byte_info->next;
  244.     }
  245.     }
  246. }
  247.